/*
---- MAIN THREAD
*/
var
  TestCarGen: CarGenerator
  TestPickup: Pickup
end
thread MAIN
  name "MAIN"

  // Init gameworld
  add_hospital_restart(-449.7836, -341.3995, 33.5024, 83.1352)
  add_hospital_restart(341.4144, -1396.291, 31.5098, 47.53)
  add_hospital_restart(360.7675, -583.4315, 27.8269, 276.9074)
  add_hospital_restart(1838.495, 3672.222, 33.2783, 206.5448)
  add_hospital_restart(-242.2981, 6325.233, 31.4271, 335.2387)
  add_police_restart(-1093.89, -807.0834, 18.2612, 42.24)
  add_police_restart(360.8818, -1581.608, 28.2931, 23.6148)
  add_police_restart(-560.5718, -132.7783, 37.0586, 210.6082)
  add_police_restart(1856.352, 3682.061, 33.2672, 210.2006)
  add_police_restart(-440.7429, 6019.889, 30.4903, 314.9315)
  add_police_restart(639.1819, 1.765, 81.7865, 238.0365)
  add_police_restart(479.6391, -976.6794, 26.9839, 331.7253)

  var
   cgModelHash: GTA.Hash
  end

  // Parked car generator in front of the Observatory - Go Go Space Monkey Blista
  @cgModelHash = MISC.GET_HASH_KEY("blista3")
  $TestCarGen = create_car_generator(-414.259, 1164.613, 326.099, 163.468, @cgModelHash)
  $TestCarGen.Active = true

  // Weapon pickup under a tree at the Epsilon Program HQ - Heavy Pistol with 500 bullets
  @cgModelHash = MISC.GET_HASH_KEY("PICKUP_WEAPON_HEAVYPISTOL")
  $TestPickup = create_pickup(-684.452, 32.96, 41.115, @cgModelHash, 0, 500, 275000)

  // Create threads
  create_thread &SaveGame
  create_thread &PlayerHangar
  create_thread &WastedBusted

  // Upon game start, player will be transported to the Observatory, and get a Stromberg car
  var
   hasModelLoaded: bool
   modelHash: GTA.Hash
  end
  @modelHash = MISC.GET_HASH_KEY("stromberg")
  STREAMING.REQUEST_MODEL(@modelHash)

  :LoadModelCheck
  wait locked
  @hasModelLoaded = STREAMING.HAS_MODEL_LOADED(@modelHash)
  if
    @hasModelLoaded != false
  jump_if_false #LoadModelCheck

  var
   groundZ: float
   playerCarHandle: GTA.Vehicle
  end
  @groundZ = 0
  STREAMING.REQUEST_COLLISION_AT_COORD(-421.53, 1187.72, 330.68)
  MISC.GET_GROUND_Z_FOR_3D_COORD(-421.53, 1187.72, 330.68, @groundZ, false, false)
  if
    @groundZ < 326.68
  jump_if_false #SpawnCar
  @groundZ = 326.68

  :SpawnCar
  @playerCarHandle = VEHICLE.CREATE_VEHICLE(@modelHash, -421.53, 1187.72, @groundZ, 0.0, false, false, false)

  var
   playerHandle: GTA.Player
   playerPed: GTA.Ped
  end
  @playerHandle = PLAYER.GET_PLAYER_INDEX()
  @playerPed = PLAYER.GET_PLAYER_PED(@playerHandle)
  PED.SET_PED_INTO_VEHICLE(@playerPed, @playerCarHandle, -1)
  ENTITY.SET_VEHICLE_AS_NO_LONGER_NEEDED(@playerCarHandle)
end

/*
---- SAVE THREAD
*/
thread SaveGame
  // Marker for Save Game
  var
    saveBlip: Blip
  end
  @saveBlip = add_blip_with_icon(-1636.52, 180.7675, 61.25654, 570, 38)
  @saveBlip.Selectable = true
  @saveBlip.LongRange = true

  // Player distance check
  var
    playerHandle: GTA.Player
    playerPed: GTA.Ped
    playerPos: Vector3
    x: float
    y: float
    z: float
    dist: float
  end

  :CheckSaveGame
  wait 0
  if and
    not is_on_mission()
    $is_player_wasted == false
    $is_player_busted == false
  jump_if_false #CheckSaveGame

  // Query player's disatance to the save spot...
  @playerHandle = PLAYER.GET_PLAYER_INDEX()
  @playerPed = PLAYER.GET_PLAYER_PED(@playerHandle)
  @playerPos = ENTITY.GET_ENTITY_COORDS(@playerPed, false)
  @x = @playerPos.x
  @y = @playerPos.y
  @z = @playerPos.z
  @dist = MISC.GET_DISTANCE_BETWEEN_COORDS(@x, @y, @z, -1636.52, 180.7675, 60.75654, false)

  // Draws a visible marker
  if
    @dist <= 50
  jump_if_false #CheckSaveGame
  GRAPHICS.DRAW_MARKER(1, -1636.52, 180.7675, 60.75654, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 192, 192, 192, false, false, 2, true, null_str, null_str, false)

  // Player can now save the game via the menu
  if
    @dist <= 1
  jump_if_false #CheckSaveGame
  gosub &SaveGameFunc

  // NOTE: player handle may not be valid, if a savegame is loaded, so we need to query player coords again...
  @playerHandle = PLAYER.GET_PLAYER_INDEX()
  @playerPed = PLAYER.GET_PLAYER_PED(@playerHandle)
  ENTITY.SET_ENTITY_COORDS(@playerPed, -1634.02, 180.7675, 60.75654, false, false, false, true)
  jump #CheckSaveGame
end

/*
---- HANGAR (Garage)
*/
thread PlayerHangar
  name "PlayerAirportHangar"
  var
    hangarMarker: Blip
  end
  @hangarMarker = add_blip_with_icon(-1656.067, -3147.411, 12.73782, 359, 38)
  @hangarMarker.Selectable = true
  @hangarMarker.LongRange = true
  @hangarMarker.ShowOnMission = true

  var
    stored: bool
    playerHandle: GTA.Player
    playerPed: GTA.Ped
    playerPos: Vector3
    x: float
    y: float
    z: float
    dist: float
  end
  @stored = false

  :MainCheck
  wait 0
  @playerHandle = PLAYER.GET_PLAYER_INDEX()
  @playerPed = PLAYER.GET_PLAYER_PED(@playerHandle)
  @playerPos = ENTITY.GET_ENTITY_COORDS(@playerPed, false)
  @x = @playerPos.x
  @y = @playerPos.y
  @z = @playerPos.z
  @dist = MISC.GET_DISTANCE_BETWEEN_COORDS(@x, @y, @z, -1656.067, -3147.411, 12.73782, true)
  if
    @dist > 50
  jump_if_false #RestoreVehicles

  :StoreVehicles
  if
    @stored == false
  jump_if_false #MainCheck

  store_cars_from_angled_cube(-1647.564, -3193.309, 8.30761, -1673.114, -3101.537, 29.47725, -28.6478955, true)
  @stored = true
  jump #MainCheck

  :RestoreVehicles
  if
    @stored != false
  jump_if_false #MainCheck
  spawn_stored_cars_in_angled_cube(-1647.564, -3193.309, 8.30761, -1673.114, -3101.537, 29.47725, -28.6478955)
  forget_stored_cars_in_angled_cube(-1647.564, -3193.309, 8.30761, -1673.114, -3101.537, 29.47725, -28.6478955)
  @stored = false
  jump #MainCheck
end


/*
---- WASTED-BUSTED THREAD
*/
var
    is_player_wasted: bool
    is_player_busted: bool
end
thread WastedBusted
  name "WastedBusted"
  $is_player_wasted = false
  $is_player_busted = false

  var
    player: GTA.Player
    intplayer: int
    dead: bool
    effecttype: string
    scenetype: string
    scenesound: string
    respawntype: string
    sc: int
    loaded: bool
    ta: float
    soundplayed: bool
  end

  :wb_proc
  wait 0
  @player = PLAYER.GET_PLAYER_INDEX()

  // Is dead
  @dead = PLAYER.IS_PLAYER_DEAD(@player)
  if
    @dead == false
  jump_if_false #wb_death_scene

  // Is arrested
  @dead = PLAYER.IS_PLAYER_BEING_ARRESTED(@player, false)
  if
    @dead == false
  jump_if_false #wb_busted_scene
  jump #wb_proc

  // Death scene
  :wb_death_scene
  $is_player_wasted = true
  gosub #wb_start_scene_Default

  :wb_death_scene_wait
  wait 0
  gosub #wb_check_scene
  @dead = PLAYER.IS_PLAYER_DEAD(@player)
  if
    @dead == false
  jump_if_false #wb_death_scene_wait
  gosub #wb_end_scene
  $is_player_wasted = false
  jump #wb_proc

  // Busted scene
  :wb_busted_scene
  $is_player_busted = true
  gosub #wb_start_scene_Default

  :wb_busted_scene_wait
  wait 0
  gosub #wb_check_scene
  @dead = PLAYER.IS_PLAYER_BEING_ARRESTED(@player, false)
  if
    @dead == false
  jump_if_false #wb_busted_scene_wait
  gosub #wb_end_scene
  $is_player_busted = false
  jump #wb_proc

  // Sub: start scene
  :wb_start_scene_Default
  @intplayer = get_internal_player_index()
  if or
    @intplayer <= 0
    @intplayer > 2
  jump_if_false #wb_start_scene_Franklin
  @effecttype = "DeathFailMichaelIn"
  jump #wb_start_scene_Wasted

  :wb_start_scene_Franklin
  if
    @intplayer == 1
  jump_if_false #wb_start_scene_Trevor
  @effecttype = "DeathFailFranklinlIn"
  jump #wb_start_scene_Wasted

  :wb_start_scene_Trevor
  @effecttype = "DeathFailTrevorlIn"

  :wb_start_scene_Wasted
  if
    $is_player_wasted != false
  jump_if_false #wb_start_scene_Busted
  @scenetype = "DEATH_SCENE"
  @scenesound = "WastedSounds"
  @respawntype = "RESPAWN_W"
  jump #wb_start_scene_Start

  :wb_start_scene_Busted
  @scenetype = "BUSTED_SCENE"
  @scenesound = "BustedSounds"
  @respawntype = "RESPAWN_B"

  :wb_start_scene_Start
  @soundplayed = false
  reset_timer(0)
  MISC.SET_TIME_SCALE(0.2)
  CAM.SET_CAM_DEATH_FAIL_EFFECT_STATE(1)

  GRAPHICS.ANIMPOSTFX_PLAY(@effecttype, 0, true)
  AUDIO.START_AUDIO_SCENE(@scenetype)
  AUDIO.REQUEST_SCRIPT_AUDIO_BANK("OFFMISSION_WASTED", false, -1)
  AUDIO.PLAY_SOUND_FRONTEND(-1, "ScreenFlash", @scenesound, true)
  AUDIO.PLAY_SOUND_FRONTEND(-1, "Bed", @scenesound, true)
  @sc = GRAPHICS.REQUEST_SCALEFORM_MOVIE("MP_BIG_MESSAGE_FREEMODE")

  :wb_start_scene_load
  wait 0
  @loaded = GRAPHICS.HAS_SCALEFORM_MOVIE_LOADED(@sc)
  if
    @loaded != false
  jump_if_false #wb_start_scene_load
  GRAPHICS.BEGIN_SCALEFORM_MOVIE_METHOD(@sc, "RESET_MOVIE")
  GRAPHICS.END_SCALEFORM_MOVIE_METHOD()
  GRAPHICS.BEGIN_SCALEFORM_MOVIE_METHOD(@sc, "SHOW_SHARD_WASTED_MP_MESSAGE")
  GRAPHICS.BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRING")
  HUD.ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL(@respawntype)
  GRAPHICS.END_TEXT_COMMAND_SCALEFORM_STRING()
  GRAPHICS.END_SCALEFORM_MOVIE_METHOD()

  :wb_start_scene_ret
  return

  // Sub: check scene
  :wb_check_scene
  GRAPHICS.DRAW_SCALEFORM_MOVIE_FULLSCREEN(@sc, 0, 0, 0, 255, 0)
  @ta = get_timer(0)
  if and
    @ta > 0.3
    @soundplayed == false
  jump_if_false #wb_cs_nosound
  @soundplayed = true
  AUDIO.PLAY_SOUND_FRONTEND(-1, "Bed", @scenesound, true)

  :wb_cs_nosound
  return

  // Sub: end scene
  :wb_end_scene
  CAM.SET_CAM_DEATH_FAIL_EFFECT_STATE(0)
  GRAPHICS.ANIMPOSTFX_STOP(@effecttype)
  MISC.SET_TIME_SCALE(1)
  AUDIO.STOP_AUDIO_SCENE(@scenetype)
  GRAPHICS.SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(@sc)

  :wb_end_scene_ret
  return
end

/*
---- SAVE GAME UTIL FUNC
NOTE: This thread is being called from a gosub; we must not use local variables!
*/
var
  SaveGameHours: int
  SaveGameMinutes: int
end
thread SaveGameFunc
  show_save_screen()

  // Advance time 8 hours
  $SaveGameHours = CLOCK.GET_CLOCK_HOURS()
  $SaveGameMinutes = CLOCK.GET_CLOCK_MINUTES()
  $SaveGameHours += 8
  if
    $SaveGameHours > 23
  jump_if_false #AdvanceTime
  $SaveGameHours -= 24

  :AdvanceTime
  CLOCK.SET_CLOCK_TIME($SaveGameHours, $SaveGameMinutes, 0) // Seconds are meaningless in GTA V

  // In case we want to reinitialize world properties, that are not saved by YOS,
  // we must do them here!
  :DoWorldReinitActions
  if
    is_saved_game_loaded()
  jump_if_false #EndSub
  // Perform reinit actions here, if any
  jump #EndSub

  :EndSub
  return
end





